package com.cancer.common.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;

public final class JDBCUtil {
	/**
	 * 取得数据库连接
	 * 
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static Connection openConnection(String url, String username, String password) {
		try {
			return DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}// getConnection
	
	/**
	 * 取得数据库连接(sqlite)
	 * 
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static Connection openConnection(String url) {
		try {
			return DriverManager.getConnection(url);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}// getConnection
	
	/**
	 * 开始事务
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static void beginTransaction(Connection conn) {
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}// beginTransaction

	/**
	 * 开始事务, 并设置事务隔离级别
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static void beginTransaction(Connection conn, int isolation) {
		try {
			conn.setAutoCommit(false);
			conn.setTransactionIsolation(isolation);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 提交事务
	 * 
	 * @author 刘俊 2015年5月12日
	 * @param conn
	 */
	public static void commit(Connection conn) {
		if (conn != null) {
			try {
				conn.commit();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}
	
	/**
	 * 事务回滚
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static void rollback(Connection conn) {
		if (conn != null) {
			try {
				conn.rollback();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}

	/**
	 * 事务回滚, 并关闭Connection
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static void rollbackAndClose(Connection conn) {
		if (conn != null) {
			try {
				try {
					conn.rollback();
				} finally {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}
	
	/**
	 * 关闭statement
	 */
	public static void closeStatement(Statement st) {
		if (st != null) {
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 关闭resultSet
	 */
	public static void closeResultSet(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 关闭数据库连接
	 */
	public static void closeConnection(Connection conn) {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 通用的关闭方法
	 * 
	 * @author 刘俊 2015年5月12日
	 * @param obj
	 */
	public static void close(AutoCloseable obj) {
		try {
			if (obj != null) obj.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 取得PreparedStatement
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static PreparedStatement getPreparedStatement(Connection conn, String sql) {
		try {
			return conn.prepareStatement(sql);
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}// getPreparedStatement
	
	/**
	 * 取得PreparedStatement并设置参数
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static PreparedStatement getPreparedStatement(Connection conn, String sql, Object[] params) {
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			setStatementPramas(ps, params);
			return ps;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}// getPreparedStatement
	
	/**
	 * 设置参数
	 * 
	 * @author 刘俊 2015年5月7日
	 * @param ps
	 * @param params
	 * @throws SQLException 
	 * @throws 如果出现SQL异常, 则会抛出
	 */
	public static void setStatementPramas(PreparedStatement ps, Object[] params) {
		if (params != null) {
			Class<java.util.Date> ud = java.util.Date.class;
			Class<java.sql.Date>  sd = java.sql.Date.class;
			try {
				for (int i = 0; i < params.length; ++i) {
					Object obj = params[i];
					if (obj == null) {
						ps.setNull(i + 1, Types.NULL);
					} else if (ud.equals(obj.getClass()) || sd.equals(obj.getClass())) {
						long t = ((java.util.Date)obj).getTime();
						ps.setTimestamp(i + 1, new java.sql.Timestamp(t));
					} else if (Timestamp.class.equals(obj.getClass())) {
						ps.setTimestamp(i + 1, (java.sql.Timestamp)obj);
					} else {
						ps.setObject(i + 1, obj);
					}
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	/**
	 * 为SQL的条件值左右两边添加%
	 * @author 刘俊
	 * @time 2015年1月20日
	 * @param value
	 * @return
	 */
	public static String addWildcardForValue(String value) {
		if (value != null) {
			return "%" + value + "%";
		} else {
			return null;
		}
	}
	
	/**
	 * 获取总页数
	 * 
	 * @author 刘俊 2015年4月24日
	 * @param totalSize		当前页
	 * @param pageSize		页大小
	 * @return
	 */
	public static int getTotalPage(int totalSize, int pageSize) {
		
		return (totalSize - 1) / pageSize + 1;
	}
	
	/**
	 * 计算起始记录位置
	 * 
	 * @author 刘俊 2015年4月24日
	 * @param pageNum		当前页
	 * @param pageSize		页大小
	 * @return
	 */
	public static int getPageOffset(int pageNum, int pageSize) {
		
		return (pageNum - 1) * pageSize;
	}
	
	/**
	 * 计算末尾记录位置
	 * 
	 * @author 刘俊 2015年4月24日	
	 * @param pageNum		当前页
	 * @param pageSize		页大小
	 * @return
	 */
	public static int getPageMaxOffset(int pageNum, int pageSize) {
		
		return pageNum * pageSize;
	}
	
	/**
	 * 计算出当前页
	 * 
	 * @author 刘俊 2016年2月29日
	 * @param pageOffset
	 * @param pageSize
	 * @return
	 */
	public static int getPageNum(int pageOffset, int pageSize) {
		
		return (pageOffset - 1) / pageSize + 1;
	}
	
}
